package org.springside.examples.showcase.fulltext;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.ansj.lucene3.AnsjAnalysis;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.NIOFSDirectory;
import org.apache.lucene.util.Version;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springside.examples.showcase.wb.entity.WbContent;
import org.springside.modules.utils.DateUtils;

public class FullTextUtils {
	private static final AnsjAnalysis ANSJ_ANALYSIS = new AnsjAnalysis();
	private static Logger logger = LoggerFactory.getLogger(FullTextUtils.class);
	private static File INDEX_DIR = new File("d:/index");

	private static Document toDocument(WbContent wb) {
		Date date = null;
		try {
			date = DateUtils.parse(wb.getIr_created_date(), "yyyy-MM-dd");
		} catch (ParseException e) {
			date = new Date();
		}

		Document doc = new Document();
		doc.add(new Field("mid", wb.getIr_mid() + "", Field.Store.YES, Field.Index.NOT_ANALYZED));
		doc.add(new Field("cdate", DateTools.timeToString(date.getTime(), DateTools.Resolution.DAY), Field.Store.YES, Field.Index.NOT_ANALYZED));
		if (wb.getIr_created_at() != null) {
			doc.add(new Field("ctime", DateTools.timeToString(wb.getIr_created_at().getTime(), DateTools.Resolution.SECOND), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_status_content() != null) {
			doc.add(new Field("contents", wb.getIr_status_content(), Field.Store.YES, Field.Index.ANALYZED));
		}
		if (wb.getIr_uid() != null) {
			doc.add(new Field("uid", wb.getIr_uid(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_screen_name() != null) {
			doc.add(new Field("nickname", wb.getIr_screen_name(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_sitename() != null) {
			doc.add(new Field("sitename", wb.getIr_sitename(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_urlname() != null) {
			doc.add(new Field("url", wb.getIr_urlname(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_retweeted_uid() != null) {
			doc.add(new Field("ruid", wb.getIr_retweeted_uid(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_retweeted_screen_name() != null) {
			doc.add(new Field("rnickname", wb.getIr_retweeted_screen_name(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_retweeted_mid() != null) {
			doc.add(new Field("rmid", wb.getIr_retweeted_mid() + "", Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_retweeted_url() != null) {
			doc.add(new Field("rurl", wb.getIr_retweeted_url(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_groupname() != null) {
			doc.add(new Field("groupname", wb.getIr_groupname(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_via() != null) {
			doc.add(new Field("via", wb.getIr_via(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		if (wb.getIr_thumbnail_pic() != null) {
			doc.add(new Field("photourl", wb.getIr_thumbnail_pic(), Field.Store.YES, Field.Index.NOT_ANALYZED));
		}
		return doc;
	}

	/** Index all text files under a directory. */
	public static String indexDocs(List<WbContent> wbs) {
		StringBuffer sbBuffer = new StringBuffer();
		try {
			IndexWriter writer = new IndexWriter(NIOFSDirectory.open(INDEX_DIR), new IndexWriterConfig(Version.LUCENE_32, ANSJ_ANALYSIS));
			// 不建立复合式索引文件，默认的情况下是复合式的索引文件。如果Field中的数据量非常大，那么很有可能在建索引的时候造成内存溢出。所以有必要限制每个Field中value的最大词数。
			// writer.setUseCompoundFile(false);
			for (WbContent wb : wbs) {
				writer.addDocument(toDocument(wb));
				sbBuffer.append(",").append(wb.getIr_mid());
			}
			writer.optimize();
			writer.close();
		} catch (IOException e) {
			logger.info(" caught a " + e.getClass() + "\n with message: " + e.getMessage());
		}
		return sbBuffer.toString();
	}

	public static List<WbContent> searchDocs(String keyword) {
		List<WbContent> wbList = new ArrayList<WbContent>();
		try {
			IndexSearcher searcher = new IndexSearcher(NIOFSDirectory.open(INDEX_DIR));
			// Term t = new Term("content", keyword);
			// Query query = new TermQuery(t);
			String[] fields = { "contents" };
			QueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_32, fields, ANSJ_ANALYSIS);
			Query query;
			try {
				query = queryParser.parse(keyword);
				TopDocs topDocs = searcher.search(query, 10);
				logger.debug("检索总理为：" + topDocs.totalHits);
				ScoreDoc[] scoreDocs = topDocs.scoreDocs;
				for (int j = 0; j < scoreDocs.length; j++) {
					try {
						ScoreDoc scoreDoc = scoreDocs[j];
						Document doc = searcher.doc(scoreDoc.doc);
						WbContent wb = new WbContent();
						wb.setIr_mid(Long.parseLong(doc.get("mid")));
						wb.setIr_created_at(DateTools.stringToDate(doc.get("ctime")));
						wb.setIr_created_date(DateUtils.format(DateTools.stringToDate(doc.get("cdate")), "yyyy-MM-dd"));
						wb.setIr_status_content(doc.get("contents"));
						wb.setIr_uid(doc.get("uid"));
						wb.setIr_screen_name(doc.get("nickname"));
						wb.setIr_sitename(doc.get("sitname"));
						wb.setIr_urlname(doc.get("url"));
						wb.setIr_retweeted_uid(doc.get("ruid"));
						wb.setIr_retweeted_screen_name(doc.get("rnickname"));
						wb.setIr_retweeted_mid(Long.parseLong(doc.get("rmid")));
						wb.setIr_retweeted_url(doc.get("rurl"));
						wb.setIr_groupname(doc.get("groupname"));
						wb.setIr_groupname(doc.get("groupname"));
						wb.setIr_thumbnail_pic(doc.get("photourl"));
						wbList.add(wb);
					} catch (NumberFormatException e) {
						logger.error("检索对象反序列化异常", e);
					} catch (ParseException e) {
						logger.error("检索对象反序列化异常", e);
					}
				}
			} catch (org.apache.lucene.queryParser.ParseException e) {
				logger.error("", e);
			}
			searcher.close();
		} catch (CorruptIndexException e) {
			logger.error("检索异常", e);
		} catch (IOException e) {
			logger.error("检索异常", e);
		}
		return wbList;
	}

	public static void main(String[] args) {
		// List<WbContent> wbs = new ArrayList<WbContent>();
		// WbContent wbContent = new WbContent();
		// wbContent.setIr_status_content("总是在为他哭时想起你 心酸委屈能不能逃离");
		// wbContent.setIr_mid(3452984828267305l);
		// wbContent.setIr_created_date("2012-06-04");
		// WbContent wb = new WbContent();
		// wb.setIr_status_content("//@煮面大招儿: 《原来爱情这么伤》~！~唱着爱情里的伤~忍不住循环播放的歌，就关注@单曲循环症LOOP");
		// wb.setIr_mid(3452984828865953l);
		// wb.setIr_created_date("2012-06-04");
		// wbs.add(wbContent);
		// wbs.add(wb);
		// FullTextUtils.indexDocs(wbs);
		// ///////////////////////////////////////////////////////////////////
		List<WbContent> searchDocs = FullTextUtils.searchDocs("香港");
		for (WbContent wbs2 : searchDocs) {
			System.out.println(wbs2.getIr_mid() + "----->" + wbs2.getIr_status_content());
		}
	}
}
